#include <iostream>
#include <fstream>
#include <string>
#include "CDiceMgr.h"
#include "pb_cfg_dice.pb.h"
#include "../mainctrl.h"

int CFamilyDiceMgr::InitClanDice (CClanEntry & stClanEntry, CClanData & stClanData)
{
    //检查值排行榜的用户是否还是家族成员
    for (int i = 0; i < stClanData._stDiceRank._stRank.Size(); i++)
    {
        CDiceRankUnit & stUnit = stClanData._stDiceRank._stRank[i];

        if (stClanEntry.HasThisMember (stUnit._uiGid))
        {
            stClanEntry._stDiceRank._stRank.AddOneItem(stUnit);
        }
    }

    return 0;
}

int CFamilyDiceMgr::DoReq(MsgReqFamilyDice &stReq, MsgAnsFamilyDice & stAns)
{
    int iRet = 0;

    int iReqType = stReq.req_type();
    unsigned int iGid = stReq.gid();

    switch( iReqType )
    {
    case CONST_DICE_GET_INFO:
        iRet = this->GetFamilyDiceInfo(iGid, stAns);
        break;
    case CONST_DICE_SHAKE_COMMON:
        iRet = this->DiceShakeCommon(iGid, stAns);
        break;
    case CONST_DICE_SHAKE_BUY:
        iRet = this->DiceShakeBuy(iGid, stAns);
        break;
    default:
        break;
    }

    return iRet;
}

//是否家族用户
bool CFamilyDiceMgr::IsClanUser(unsigned int uiGid)
{
    int iClanIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(uiGid);
    if (iClanIndex < 0)
    {
        CT_ERROR(("gid = %u not in any Clan", uiGid));
        return false;
    }
    //CClanEntry & stClanEntry = CMainCtrl::m_pstMain->m_stClanMgr._stClanEntryHash[iClanIndex];

    return true;
}

int CFamilyDiceMgr::GetRandomRange(int iMin, int iMax)
{
    int iResult = 0;

    while(true)
    {
        iResult = random()%(iMax-iMin) + iMin;
        if( iResult>=iMin && iResult<iMax ) break;
    }

    return iResult;
}

//免费投骰子
int CFamilyDiceMgr::DiceShakeCommon(unsigned int uiGid, MsgAnsFamilyDice & stAns)
{
    int iRet = 0;

    //cmd中已经检查用户合法性，这里放心使用
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(uiGid);
    CPlayerDetailInfo& stPlayerDetailInfo = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];

    iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stPlayerDetailInfo._uiGID);
    CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

    //家族检查 //家族等级暂时不检查
    if( !this->IsClanUser( uiGid ) )
    {
        return ERROR_CLAN_NOT_EXIST;
    }

    //剩余次数
    if( stPlayerDetailInfo._stDiceData._sDiceRestCounts.Get(CMainCtrl::m_pstMain->m_iNow)<=0 )
    {
        CT_ERROR(("gid = %u, hasn't free counts to dice", uiGid));
        return ERROR_USEOUT_FREE_COUNTS;
    }

    iRet = this->DiceShake(stPlayerDetailInfo, stAns);
    CHECK_RETURN(iRet);

    //从剩余次数中减少一次
    stPlayerDetailInfo._stDiceData._sDiceRestCounts.Sub(1, CMainCtrl::m_pstMain->m_iNow);

    if( iRet==RET_OK )
    {
        m_bStatusChange = true;
        this->UpdateDiceStatus(stPlayerDetailInfo);

        this->GetFamilyDiceBaseInfo( stPlayerDetailInfo, stAns );
    }

    if (GetDiceCount(stPlayerBaseInfo, stPlayerDetailInfo) <= 0)
    {
        CMainCtrl::m_pstMain->m_stActMgr.NotifyActListToSelf(
            stPlayerDetailInfo._uiGID);
    }

    return iRet;
}

//金币购买投骰子
int CFamilyDiceMgr::DiceShakeBuy(unsigned int uiGid, MsgAnsFamilyDice & stAns)
{
    int iRet = 0;

    //cmd中已经检查用户合法性，这里放心使用
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(uiGid);
    CPlayerDetailInfo& stPlayerDetailInfo = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];

    iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stPlayerDetailInfo._uiGID);
    CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

    //家族检查 //家族等级暂时不检查
    if( !this->IsClanUser( uiGid ) )
    {
        return ERROR_CLAN_NOT_EXIST;
    }

    //检查是否已经超过可以购买的次数上限
    int iBuyCounts = stPlayerDetailInfo._stDiceData._sBuyCounts.Get(CMainCtrl::m_pstMain->m_iNow);
    //购买上限从vip中获取
    int iMaxBuyCount = 0;
    iRet = CMainCtrl::m_pstMain->m_stVipMgr.GetVipDestNum(stPlayerBaseInfo._chVipLevel, VIP_MODULE_ID_17, iMaxBuyCount);
    if (RET_OK != iRet)
    {
        return ERROR_BEYOND_BUY_COUNTS;
    }
    //if( iBuyCounts>CONST_DAILY_DICE_BUY_COUNTS )
    if( iBuyCounts>=iMaxBuyCount)
    {
        CT_ERROR(("gid = %u, has buy %d counts beyond max %d to dice", uiGid, iBuyCounts, iMaxBuyCount));
        return ERROR_BEYOND_BUY_COUNTS;
    }

    //检查金币消耗
    CPayDiceConfigData stPayDiceData;
    iRet = this->_stFamilyDiceCfg.GetPayDiceConfig(iBuyCounts+1, stPayDiceData);
    CHECK_RETURN(iRet);
    int iConsumeGoldNum = stPayDiceData.iNeedGold;
    if( iConsumeGoldNum > stPlayerBaseInfo._iGold )
    {
        CT_WARNING(("gid = %u, not enough gold to dice pay", uiGid));
        return ERROR_DICE_PAY_NOT_ENOUGH_GOLD;
    }

    //iRet = this->DiceShake(stPlayerDetailInfo, stAns);

    iRet = CMainCtrl::m_pstMain->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_37, iConsumeGoldNum);
    CHECK_RETURN(iRet);
    if( iRet==RET_OK )
    {
        //金币购买次数增加一次
        stPlayerDetailInfo._stDiceData._sBuyCounts.Add(1, CMainCtrl::m_pstMain->m_iNow);

        //增加一次
        stPlayerDetailInfo._stDiceData._sDiceRestCounts.Add(1, CMainCtrl::m_pstMain->m_iNow);

        m_bStatusChange = true;
        iRet = this->UpdateDiceStatus(stPlayerDetailInfo);

        this->GetFamilyDiceBaseInfo( stPlayerDetailInfo, stAns );

        //推送金币剩余信息
        CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(uiGid, NOTIFY_USER_MONEY);
    }

    return iRet;
}

int CFamilyDiceMgr::GetDiceCount(CPlayerBaseInfo& stPlayerBase,
                                 CPlayerDetailInfo& stPlayerDetail)
{
    int iRet = 0;
    int iBuyCount = 0;
    int iFreeCount = 0;
    int iMaxBuyCount = 0;

    iFreeCount = stPlayerDetail._stDiceData._sDiceRestCounts.Get(
        CMainCtrl::m_pstMain->m_iNow);

    //检查是否已经超过可以购买的次数上限
    iBuyCount = stPlayerDetail._stDiceData._sBuyCounts.Get(
        CMainCtrl::m_pstMain->m_iNow);

    //购买上限从vip中获取
    //iRet = CMainCtrl::m_pstMain->m_stVipMgr.GetVipDestNum(
    //    stPlayerBase._chVipLevel, VIP_MODULE_ID_17, iMaxBuyCount);
    iRet = CMainCtrl::m_pstMain->m_stVipMgr.GetVipDestNum(
        MAX_VIP_LEVEL - 1, VIP_MODULE_ID_17, iMaxBuyCount);
    if (iRet)
    {
        CT_ERROR(("role(%u) vip level(%d) dest num buy count(%d) error(%d)",
            stPlayerBase._uiGID,stPlayerBase._chVipLevel,iMaxBuyCount,iRet));
        return 0;
    }

    return iMaxBuyCount - iBuyCount + iFreeCount;
}

int CFamilyDiceMgr::DiceShake(CPlayerDetailInfo& stPlayerDetailInfo, MsgAnsFamilyDice & stAns)
{
    int iRet = 0;
    int iNowTime = CMainCtrl::m_pstMain->m_iNow;

    CDiceAwardConfigData stData;
    int iNowGridPos = stPlayerDetailInfo._stDiceData._sGridId.Get(iNowTime);
    stAns.set_grid_pos_before( iNowGridPos );

    int iDiceRandomCount = 0;   //骰子1点数
    int iDiceRandomCount2 = 0;  //骰子2点数
    //起始位置
    if( iNowGridPos>0 )
    {
        //当前位置是否两个骰子
        iRet = this->_stFamilyDiceCfg.GetDiceGridConfig(iNowGridPos, stData);
        CHECK_RETURN(iRet);
        if( stData.iGridType==CONST_GRID_TYPE_SHAKE_TWO_DICE )
        {
            iDiceRandomCount2 = GetRandomRange(1, 7);
            stAns.add_shake_dice_nums( iDiceRandomCount2 ); //返回点数给前台
        }
    }

    iDiceRandomCount = GetRandomRange(1, 7);
    stAns.add_shake_dice_nums( iDiceRandomCount );  //返回点数给前台

    short iNewGridPos = (short)(iNowGridPos + iDiceRandomCount + iDiceRandomCount2);

    int iBestWeekPos = 0;

    //超过最大层，返回第一层
    if( iNewGridPos> _stFamilyDiceCfg.GetGridCount())
    {
        iNewGridPos -= _stFamilyDiceCfg.GetGridCount();
        stPlayerDetailInfo._stDiceData._sGridId.Sub( iNowGridPos, CMainCtrl::m_pstMain->m_iNow ); //先减为0
        stPlayerDetailInfo._stDiceData._sGridId.Add( iNewGridPos, CMainCtrl::m_pstMain->m_iNow );

        iBestWeekPos = _stFamilyDiceCfg.GetGridCount();
    }
    else
    {
        //设置新的格子位置
        stPlayerDetailInfo._stDiceData._sGridId.Add( iDiceRandomCount + iDiceRandomCount2, CMainCtrl::m_pstMain->m_iNow );

        iBestWeekPos = CT_MAX((stPlayerDetailInfo._stDiceData._sGridId.Get(iNowTime)), iBestWeekPos);
    }

    //更新本周最佳记录
    UpdateBestRecord (stPlayerDetailInfo, iBestWeekPos);

    iRet = this->_stFamilyDiceCfg.GetDiceGridConfig(iNewGridPos, stData);
    CHECK_RETURN(iRet);

    int iOldLayer = (int)ceil((iNowGridPos*1.0)/CONST_DICE_GRIDS_ONE_LAYER);
    const int OLD_LAYER = iOldLayer;
    int iNewLayer = (int)ceil((iNewGridPos*1.0)/CONST_DICE_GRIDS_ONE_LAYER);
    iOldLayer = (iOldLayer==0) ? (iOldLayer+1):iOldLayer;

    //获取用户的等级奖励系数
    CDiceAwardRateData stAwardRateData;
    int iIndex = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash.HashFind(stPlayerDetailInfo._uiGID);
    CPlayerBaseInfo& stPlayerBaseInfo = CMainCtrl::m_pstMain->m_stPlayerBaseInfoHash[iIndex];

    iRet = this->_stFamilyDiceCfg.GetAwardRateConfig(iNewLayer, stAwardRateData);
    CHECK_RETURN(iRet);

    CDropItem stDropItem;  //奖励物品
    switch( stData.iGridType )
    {
    case CONST_GRID_TYPE_AWARD: //银币和经验的数值与玩家等级相关，贡献度为定值奖励
        iRet = this->GetAwardItems( stPlayerDetailInfo._uiGID, stPlayerBaseInfo._shLevel, stData.award, stAwardRateData, stDropItem );
        break;
    case CONST_GRID_TYPE_ADD_ONE_TIMES:
        stPlayerDetailInfo._stDiceData._sDiceRestCounts.Add(1, CMainCtrl::m_pstMain->m_iNow);
        break;
    case CONST_GRID_TYPE_LEVEL_START:
    case CONST_GRID_TYPE_SHAKE_TWO_DICE:
    default:
        break;
    }
    CHECK_RETURN(iRet);

    //显示给前台 返回奖励信息
    stDropItem.GetPBMsg(stPlayerDetailInfo._uiGID, *(stAns.mutable_awards()));

    //检查升层级给于相应奖励
    while( iOldLayer!=iNewLayer )
    {
        CDiceLevelAwardConfigData stLayerAwardData;
        iRet = this->_stFamilyDiceCfg.GetLevelAwardConfig( iOldLayer, stLayerAwardData);
        CHECK_RETURN(iRet);

        iRet = this->GetLevelAwardItems(stPlayerDetailInfo._uiGID, stLayerAwardData, stDropItem);
        CHECK_RETURN(iRet);

        iOldLayer++;

        if (iOldLayer > _stFamilyDiceCfg.GetGridCount() / CONST_DICE_GRIDS_ONE_LAYER)
        {
            iOldLayer = 1;
        }
    }

    if( stDropItem.Size()>0 )
    {
        iRet = this->TriggerAward(stPlayerDetailInfo._uiGID, stDropItem, stAns);
        if (iRet)
        {
            CT_ERROR(("%d, %d", stPlayerDetailInfo._uiGID, iRet));
            return iRet;
        }

        //统计今日获得的奖励
        int iNowTime = CMainCtrl::m_pstMain->m_iNow;
        for (int i = 0; i < stDropItem.Size(); ++i)
        {
            CDropItemData & stDropItemData = stDropItem.GetDropItemData(i);
            switch (stDropItemData._ucItemType)
            {
            case ITEM_TYPE_SILVER:
                {
                    stPlayerDetailInfo._stDiceData._iDailySilver.Add(stDropItemData._iItemCount, iNowTime);
                }
                break;

            case ITEM_TYPE_EXP:
                {
                    stPlayerDetailInfo._stDiceData._iDailyExp.Add(stDropItemData._iItemCount, iNowTime);
                }
                break;

            case ITEM_TYPE_REPUTATION:
                {
                    stPlayerDetailInfo._stDiceData._iDailyRepution.Add(stDropItemData._iItemCount, iNowTime);
                }
                break;

            case ITEM_TYPE_CONTRIBUTION:
                {
                    stPlayerDetailInfo._stDiceData._iDailyContri.Add(stDropItemData._iItemCount, iNowTime);
                }
                break;
            }
        }
    }

    //跑马灯
    for (int i = 0; i < (iNewLayer - OLD_LAYER); ++i)
    {
        int iCheckLayer = OLD_LAYER + i + 1;
        if (iCheckLayer >= 20 && iCheckLayer % 5 == 0)//大于等于20级且是5的倍数
        {
            //跑马灯
            MsgTips stTips;
            stTips.set_type(1073);
            stTips.add_tip_argument(CMainCtrl::m_pstMain->m_stRoleMgr.GetRoleName(stPlayerDetailInfo._uiGID));
            stTips.add_tip_argument(CTStringUtils::IntToString(iNewLayer));
            stTips.add_tip_argument(CTStringUtils::IntToString(stPlayerDetailInfo._stDiceData._iDailySilver.Get(CMainCtrl::m_pstMain->m_iNow)));
            stTips.add_tip_argument(CTStringUtils::IntToString(stPlayerDetailInfo._stDiceData._iDailyExp.Get(CMainCtrl::m_pstMain->m_iNow)));
            stTips.add_tip_argument(CTStringUtils::IntToString(stPlayerDetailInfo._stDiceData._iDailyRepution.Get(CMainCtrl::m_pstMain->m_iNow)));
            stTips.add_tip_argument(CTStringUtils::IntToString(stPlayerDetailInfo._stDiceData._iDailyContri.Get(CMainCtrl::m_pstMain->m_iNow)));
            CMainCtrl::m_pstMain->SendOnlineTips(stTips);
            break;
        }
    }

    return iRet;
}

//触发奖励
int CFamilyDiceMgr::TriggerAward(unsigned int uiGid, CDropItem& stDropItem, MsgAnsFamilyDice& stAns)
{
    int iRet = 0;

    //assign award items to user
    stDropItem.SetOssModule(OSS_MODULE_DICE);
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.DropItem(NULL, uiGid, stDropItem);
    return iRet;
}

int CFamilyDiceMgr::GetLevelAwardItems(unsigned int uiGid, CDiceLevelAwardConfigData& stData, CDropItem& stDropItem)
{
    int iRet = 0;
    for( int i=0; i<stData._aTAwards.Size(); ++i )
    {
        CDropItemData stDropItemData;
        CMainCtrl::m_pstMain->m_stItemMgr.GetDropItemData(uiGid, stData._aTAwards[i].iAwardItemType,
            stData._aTAwards[i].iAwardItemId, NULL, COMM_MOD, stData._aTAwards[i].iAwardNum, stDropItemData);

        iRet = stDropItem.Drop(stDropItemData);
        CHECK_RETURN(iRet);
    }

    return iRet;
}

//获取物品
int CFamilyDiceMgr::GetAwardItems(unsigned int uiGid, short shLevel, TAward& award, CDiceAwardRateData& stAwardRateData, CDropItem& stDropItem)
{
    int iDropCount = 0;

    unsigned char ucType = (unsigned char)(award.iAwardItemType);
    if( award.iAwardItemType == ITEM_TYPE_LEVEL_EXP ) //等级奖励基数
    {
        iDropCount = stAwardRateData.iExperAwardRate;
    }
    else if( award.iAwardItemType== ITEM_TYPE_LEVEL_SILVER )
    {
        iDropCount = stAwardRateData.iSilverAwardRate;
    }
    else if( award.iAwardItemType==ITEM_TYPE_CONTRIBUTION )
    {
        iDropCount = stAwardRateData.iContribuAward;
    }
    else
    {
        iDropCount = 0;
    }

    CDropItemData stDropItemData;
    int iRet = RET_OK;
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetDropItemData(uiGid, ucType, award.iAwardItemId, NULL, COMM_MOD, iDropCount, stDropItemData);
    if (iRet)
    {
        CT_ERROR (("%d, %d, %d", uiGid, award.iAwardItemType, award.iAwardItemId, iDropCount));
        return iRet;
    }

    stDropItem.Drop(stDropItemData);
    return RET_OK;
}

//获取基本信息
int CFamilyDiceMgr::GetFamilyDiceBaseInfo(CPlayerDetailInfo& stPlayerDetailInfo, MsgAnsFamilyDice & stAns)
{
    stAns.set_grid_pos(stPlayerDetailInfo._stDiceData._sGridId.Get(CMainCtrl::m_pstMain->m_iNow));
    stAns.set_rest_counts(stPlayerDetailInfo._stDiceData._sDiceRestCounts.Get(CMainCtrl::m_pstMain->m_iNow));
    stAns.set_buy_counts(stPlayerDetailInfo._stDiceData._sBuyCounts.Get(CMainCtrl::m_pstMain->m_iNow));
    stAns.set_sum_repution(stPlayerDetailInfo._stDiceData._iDailyRepution.Get(CMainCtrl::m_pstMain->m_iNow));
    stAns.set_sum_exper(stPlayerDetailInfo._stDiceData._iDailyExp.Get(CMainCtrl::m_pstMain->m_iNow));
    stAns.set_sum_silver(stPlayerDetailInfo._stDiceData._iDailySilver.Get(CMainCtrl::m_pstMain->m_iNow));
    stAns.set_sum_contribute(stPlayerDetailInfo._stDiceData._iDailyContri.Get(CMainCtrl::m_pstMain->m_iNow));
    stAns.set_best_week_grid(stPlayerDetailInfo._stDiceData._iWeekBestGrid);

    int iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(stPlayerDetailInfo._uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("%d, %d",stPlayerDetailInfo._uiGID, iIndex));
        return 0;
    }

    CClanEntry & stClanEntry = CMainCtrl::m_pstMain->m_stClanMgr.GetClanEntry(iIndex);
    CDiceRank & stDiceRank = stClanEntry._stDiceRank;
    for (int i = 0; i < stDiceRank._stRank.Size(); i++)
    {
        MsgFamilyDiceRank * pstRank = stAns.add_ranks ();
        pstRank->set_rank(i+1);
        pstRank->set_name(CMainCtrl::m_pstMain->m_stRoleMgr.GetRoleName(stDiceRank._stRank[i]._uiGid));
        pstRank->set_now_grid (stDiceRank._stRank[i]._iBeseWeekPos);
    }

    return 0;
}

//获取家族闯关信息
int CFamilyDiceMgr::GetFamilyDiceInfo(unsigned int uiGid, MsgAnsFamilyDice & stAns)
{
    int iRet = 0;

    int iIndex = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash.HashFind(uiGid);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", uiGid));
        return ERROR_NO_SUCH_USER;
    }
    CPlayerDetailInfo& stPlayerDetailInfo = CMainCtrl::m_pstMain->m_stPlayerDetailInfoHash[iIndex];

    //家族检查 //家族等级暂时不检查
    if( !this->IsClanUser( uiGid ) )
    {
        return ERROR_CLAN_NOT_EXIST;
    }

    this->GetFamilyDiceBaseInfo( stPlayerDetailInfo, stAns );

    return iRet;
}

int CFamilyDiceMgr::UpdateDiceStatus(CPlayerDetailInfo & stPlayerDetail)
{
    if( this->m_bStatusChange )
    {
        //保存数据
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        stKey.m_u64ID = stPlayerDetail._uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerDetail, VOP_UPDATE);
    }

    this->m_bStatusChange = false;

    return 0;
}

int CFamilyDiceMgr::LoadConfig(const char* szCfgPath)
{
    int iRet = 0;

    if (szCfgPath == NULL)
    {
        CT_ERROR(("Family dice Cfg Path is null"));
        return RET_SYSTEM_FAIL;
    }

    pb_cfg_dice stFamilyDiceCfg;
    std::fstream stFileInput(szCfgPath, std::ios::in | std::ios::binary);
    if (!stFamilyDiceCfg.ParseFromIstream(&stFileInput))
    {
        CT_ERROR(("Failed to Parse family dice config!"));
        return RET_SYSTEM_FAIL;
    }

    //闯关格子配置文件内容
    CT_TRACE(("dice grid config count %d", stFamilyDiceCfg.dice_award_rows_size()));
    for (int i = 0; i < stFamilyDiceCfg.dice_award_rows_size(); ++i)
    {
        const pb_cfg_dice_pb_cfg_dice_award_unit& stPBUnit = stFamilyDiceCfg.dice_award_rows(i);

        CDiceAwardConfigData stDataConfig;

        stDataConfig.iGridId = stPBUnit.grid_id();
        stDataConfig.iGridType = stPBUnit.grid_type();

        stDataConfig.award.iAwardItemType = stPBUnit.award_item_type();
        stDataConfig.award.iAwardItemId = stPBUnit.award_item_id();
        stDataConfig.award.iAwardNum = stPBUnit.award_num();

        stDataConfig._bHasConfig = true;
        iRet = _stFamilyDiceCfg.AddDiceGridConfig(stDataConfig);
        CT_RETURN(iRet);
    }

    //金币购买骰子次数遵旨
    for (int i = 0; i < stFamilyDiceCfg.pay_dice_rows_size(); ++i)
    {
        const pb_cfg_dice_pb_cfg_pay_dice_unit& stPBUnit = stFamilyDiceCfg.pay_dice_rows(i);

        CPayDiceConfigData stDataConfig;

        stDataConfig.iTimes = stPBUnit.buy_times();
        stDataConfig.iNeedGold = stPBUnit.need_gold();

        stDataConfig._bHasConfig = true;
        iRet = _stFamilyDiceCfg.AddPayDiceConfig(stDataConfig);
        CT_RETURN(iRet);
    }

    //等级奖励系数
    for (int i = 0; i < stFamilyDiceCfg.award_rates_rows_size(); ++i)
    {
        const pb_cfg_dice_pb_cfg_award_rates_unit& stPBUnit = stFamilyDiceCfg.award_rates_rows(i);

        CDiceAwardRateData stDataConfig;

        stDataConfig.iDiceLevel = stPBUnit.role_level();
        stDataConfig.iSilverAwardRate = stPBUnit.silver_award_rate();
        stDataConfig.iExperAwardRate = stPBUnit.exper_award_rate();
        stDataConfig.iContribuAward = stPBUnit.contribu();

        stDataConfig._bHasConfig = true;
        iRet = _stFamilyDiceCfg.AddAwardRateConfig(stDataConfig);
        CT_RETURN(iRet);
    }

    //闯关层级奖励
    for (int i = 0; i < stFamilyDiceCfg.dice_level_award_rows_size(); ++i)
    {
        const pb_cfg_dice_pb_cfg_dice_level_award_unit& stPBUnit = stFamilyDiceCfg.dice_level_award_rows(i);

        TAward stAwardData;
        int iLayer = stPBUnit.level();

        stAwardData.iAwardItemType = stPBUnit.award_item_type();
        stAwardData.iAwardItemId = stPBUnit.award_item_id();
        stAwardData.iAwardNum = stPBUnit.award_num();

        iRet = _stFamilyDiceCfg.AddLevelAwardConfig(iLayer, stAwardData);
        CT_RETURN(iRet);
    }

    //排行奖励
    for (int i = 0; i < stFamilyDiceCfg.rank_award_rows_size (); ++i)
    {
        const pb_cfg_dice_pb_cfg_rank_award_unit & stPBUnit = stFamilyDiceCfg.rank_award_rows(i);

        if (ITEM_TYPE_GIFT != stPBUnit.item_type())
        {
            CT_ERROR(("%d",stPBUnit.item_type()));
            return ERROR_DICE_RANK_AWARD_CONFIG;
        }

        CDropItemData stAwardData;
        stAwardData._ucItemType = stPBUnit.item_type();
        stAwardData._usItemConfigID = stPBUnit.item_id();
        stAwardData._iItemCount = stPBUnit.item_cnt();

        iRet = _stFamilyDiceCfg.AddRankConfig(stPBUnit.rank(), stAwardData);
        CT_RETURN(iRet);
    }

    if (MAX_DICE_RANK_SIZE != _stFamilyDiceCfg._astDiceRankAward.m_iUsedCount)
    {
        CT_ERROR(("%d",_stFamilyDiceCfg._astDiceRankAward.m_iUsedCount));
        return ERROR_DICE_RANK_AWARD_CONFIG;
    }

    return 0;
}

void CFamilyDiceMgr::InitDiceBestRecord (CPlayerDetailInfo& stPlayerDetail, int iNowTime)
{
    if (iNowTime < stPlayerDetail._stDiceData._iNextBestTime)
    {
        return ;
    }

    if (0 == stPlayerDetail._stDiceData._iNextBestTime)
    {
        stPlayerDetail._stDiceData._iWeekBestGrid = stPlayerDetail._stDiceData._sGridId.Get(iNowTime, 0);
    }
    else
    {
        stPlayerDetail._stDiceData._iWeekBestGrid = 0;
    }

    stPlayerDetail._stDiceData._iNextBestTime = GetAccountTime (iNowTime);

    //数据入库
    UpdateDiceStatus(stPlayerDetail);

    CT_TRACE(("InitDiceBestRecord %d, %d, %d, %d",  stPlayerDetail._uiGID, iNowTime, stPlayerDetail._stDiceData._iNextBestTime, stPlayerDetail._stDiceData._iWeekBestGrid));
}

void CFamilyDiceMgr::UpdateBestRecord (CPlayerDetailInfo& stPlayerDetail, int iBestWeekPos)
{
    if (iBestWeekPos <= stPlayerDetail._stDiceData._iWeekBestGrid)
    {
        return ;
    }

    stPlayerDetail._stDiceData._iWeekBestGrid = iBestWeekPos;

    int iIndex = CMainCtrl::m_pstMain->m_stClanMgr.GetClanIndex(stPlayerDetail._uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("%d, %d",stPlayerDetail._uiGID, iIndex));
        return ;
    }

    CClanEntry & stClanEntry = CMainCtrl::m_pstMain->m_stClanMgr.GetClanEntry(iIndex);

    stClanEntry.UpdateDiceRank(stPlayerDetail._uiGID, iBestWeekPos);

    CMainCtrl::m_pstMain->m_stClanMgr.UpdateToDB(stClanEntry._uiClanId);
}

int CFamilyDiceMgr::GetDiceRankBonus (unsigned char ucRank, CDropItemData & stBonus)
{
    return _stFamilyDiceCfg.GetRankConfig(ucRank, stBonus);
}

int CFamilyDiceMgr::GetAccountTime (int iNowTime)
{
    CTTime stTime(iNowTime);

    struct tm stTm;
    stTime.GetLocalTm(&stTm);
    stTm.tm_hour = 0;
    stTm.tm_min = 0;
    stTm.tm_sec = 0;

    stTime = CTTime(stTm);  //今天的零点结算

    //tm_wday 周天为0, 周一为1, 周二为2
    if (1 == stTm.tm_wday)
    {
        //如果当天是周一的话
        return (stTime.GetTime() + 7 * 86400);
    }

    return  (stTime.GetTime() + ((8 - stTm.tm_wday) % 7 )* 86400);
}
